package com.jiudengnile.liushu.biz.ao.impl;

import java.util.List;

import wint.help.biz.result.Result;
import wint.help.biz.result.ResultSupport;
import wint.help.biz.result.ResultType;
import wint.lang.utils.CollectionUtil;
import wint.lang.utils.StringUtil;

import com.jiudengnile.liushu.biz.ao.PermissionAO;
import com.jiudengnile.liushu.biz.bo.BaseUserBO;
import com.jiudengnile.liushu.biz.bo.PermissionBO;
import com.jiudengnile.liushu.biz.constants.PermissionCodes;
import com.jiudengnile.liushu.biz.domains.BaseUserDO;
import com.jiudengnile.liushu.biz.domains.permission.PermissionDO;
import com.jiudengnile.liushu.biz.domains.permission.PermissionUserDO;
import com.jiudengnile.liushu.biz.query.ListWithTotalCount;
import com.jiudengnile.liushu.biz.query.PermissionQuery;
import com.jiudengnile.liushu.biz.resultcodes.PermissionResultCodes;
import com.jiudengnile.liushu.biz.resultcodes.UserResultCodes;
import com.jiudengnile.liushu.common.request.RequestUser;

public class PermissionAOImpl extends BaseAO implements PermissionAO {

	private PermissionBO permissionBO;
	
	private BaseUserBO baseUserBO;
	
	protected boolean checkPermission(Result result) {
		RequestUser requestUser = this.getRequestUser();
		if (requestUser == null || !requestUser.isLogin()) {
			result.setResultCode(PermissionResultCodes.NO_PERMISSION);
			return false;
		}
		if (!permissionBO.hasPermission(requestUser.getUserId(), PermissionCodes.PERMISSION_OPERATE)) {
			result.setResultCode(PermissionResultCodes.NO_PERMISSION);
			return false;
		}
		return true;
	}
	
	@Override
	public Result viewAddUserToPermission(long permissionId) {
		Result result = new ResultSupport(false);
		try {
			if (!checkPermission(result)) {
				return result;
			}
			
			PermissionDO permission = permissionBO.getPermissionById(permissionId);
			if (permission == null) {
				result.setResultCode(PermissionResultCodes.PERMISSION_HAS_NOT_EXIST);
				return result;
			}
			
			result.getModels().put("permission", permission);
			result.setSuccess(true);
		} catch (Exception e) {
			log.error("viewAddUserToPermission error", e);
		}
		return result;
	}

	@Override
	public Result addUserToPermission(long permissionId, String nicks) {
		Result result = new ResultSupport(false);
		try {
			if (!checkPermission(result)) {
				return result;
			}
			
			PermissionDO permission = permissionBO.getPermissionById(permissionId);
			if (permission == null) {
				result.setResultCode(PermissionResultCodes.PERMISSION_HAS_NOT_EXIST);
				return result;
			}
			
			List<String> notExistNicks = CollectionUtil.newArrayList();
			List<String> nickList = StringUtil.splitTrim(nicks, "[,;]");
			int hasPermissionCount = 0;
			int totalCount = 0;
			for (String nick : nickList) {
				if (StringUtil.isEmpty(nick)) {
					continue;
				}
				++totalCount;
				BaseUserDO baseUserDO = baseUserBO.queryByNick(nick);
				if (baseUserDO == null) {
					notExistNicks.add(nick);
					continue;
				}
				
				if (permissionBO.hasPermission(baseUserDO.getId(), permission.getCode())) {
					++hasPermissionCount;
					continue;
				}
				
				PermissionUserDO permissionUserDO = new PermissionUserDO();
				permissionUserDO.setPermissionCode(permission.getCode());
				permissionUserDO.setPermissionId(permission.getId());
				permissionUserDO.setUserId(baseUserDO.getId());
				
				permissionBO.createPermissionUser(permissionUserDO);
			}
			
			if (totalCount == notExistNicks.size()) {
				result.setResultType(ResultType.CURRENT_TARGET);
				result.setResultCode(UserResultCodes.USER_NOT_EXIST_BY_NICK_FOR_ADD_PERMISSION);
				return result;
			}
			
			if (totalCount == hasPermissionCount) {
				result.setResultType(ResultType.CURRENT_TARGET);
				result.setResultCode(PermissionResultCodes.PERMISSION_USER_HAS_BEEN_EXIST);
				return result;
			}
			
			if (totalCount == hasPermissionCount + notExistNicks.size()) {
				result.setResultType(ResultType.CURRENT_TARGET);
				result.setResultCode(PermissionResultCodes.PERMISSION_BY_USER_NOT_EXIST_OR_HAS_PERMISSION);
				return result;
			}
			
			result.getModels().put("notExistNicks", notExistNicks);
			result.getModels().put("permission", permission);
			result.setSuccess(true);
		} catch (Exception e) {
			log.error("addUserToPermission error", e);
		}
		return result;
	}
	
	@Override
	public Result permissionUserList(int page, long permissionId) {
		Result result = new ResultSupport(false);
		try {
			if (!checkPermission(result)) {
				return result;
			}
			
			PermissionDO permission = permissionBO.getPermissionById(permissionId);
			if (permission == null) {
				result.setResultCode(PermissionResultCodes.PERMISSION_HAS_NOT_EXIST);
				return result;
			}
			
			PermissionQuery permissionQuery = new PermissionQuery();
			permissionQuery.setPageNo(page);
			permissionQuery.setPermissionId(permissionId);
			permissionQuery.setPageSize(50);
			
			ListWithTotalCount<BaseUserDO> baseUsers = permissionBO.getUserByPermission(permissionQuery);
			permissionQuery.setTotalResultCount(baseUsers.getTotalCount());
			
			result.getModels().put("permission", permission);
			result.getModels().put("baseUsers", baseUsers);
			result.getModels().put("permissionQuery", permissionQuery);
			result.setSuccess(true);
		} catch (Exception e) {
			log.error("permissionUserList error", e);
		}
		return result;
	}

	@Override
	public Result createPermission(PermissionDO permissionDO) {
		Result result = new ResultSupport(false);
		try {
			if (!checkPermission(result)) {
				return result;
			}
			PermissionDO inDb = permissionBO.getPermissionByCode(permissionDO.getCode());
			if (inDb != null) {
				result.setResultCode(PermissionResultCodes.PERMISSION_CODE_HAS_BEEN_EXIST);
				result.setResultType(ResultType.CURRENT_TARGET);
				return result;
			}
			
			permissionBO.createPermission(permissionDO);
			
			result.setSuccess(true);
		} catch (Exception e) {
			log.error("createPermission error", e);
		}
		return result;
	}

	public Result listPermissions(int page) {
		Result result = new ResultSupport(true);
		try {
			if (!checkPermission(result)) {
				return result;
			}
			PermissionQuery permissionQuery = new PermissionQuery();
			permissionQuery.setPageNo(page);
			permissionQuery.setPageSize(100);
			ListWithTotalCount<PermissionDO> permissions = permissionBO.getPermissionForPage(permissionQuery);
			permissionQuery.setTotalResultCount(permissions.getTotalCount());
			
			result.getModels().put("permissions", permissions);
			result.getModels().put("permissionQuery", permissionQuery);
			result.setSuccess(true);
		} catch (Exception e) {
			log.error("listPermissions error", e);
		}
		return result;
	}

	public void setPermissionBO(PermissionBO permissionBO) {
		this.permissionBO = permissionBO;
	}

	public void setBaseUserBO(BaseUserBO baseUserBO) {
		this.baseUserBO = baseUserBO;
	}

}
